﻿using Shop.Collect;
using Shop.LocalEvent;
using Shop.Model.Category;
using Shop.Model.DB;
using Shop.RemoteModel.Category.Model;
using Shop.Service.Helper;
using Shop.Service.Interface;
using WeDonekRpc.Helper;

namespace Shop.Service.lmpl
{
    internal class CategoryService : ICategoryService
    {
        private readonly ICategoryCollect _Service;

        public CategoryService (ICategoryCollect service)
        {
            this._Service = service;
        }
        public CategoryDatum Get (long id)
        {
            return this._Service.Get<CategoryDatum>(id);
        }
        public long Add (CategoryAdd add)
        {
            return this._Service.Add(add);
        }
        public void Delete (long id)
        {
            DBCategory category = this._Service.Get(id);
            if (category.IsEnable)
            {
                throw new ErrorException("shop.category.already.enable");
            }
            long[] subId = this._Service.GetSubId(category);
            this._Service.Delete(category, subId);
            new CategoryLocalEvent
            {
                Category = category,
                SubId = subId
            }.AsyncPublic();
        }
        public CategoryFullTree[] GetFullTree ()
        {
            GoodsCategory[] dtos = this._Service.GetAll();
            return dtos.GetTree();
        }

        public bool Set (long id, CategorySet datum)
        {
            DBCategory category = this._Service.Get(id);
            return this._Service.Set(category, datum);
        }

        public Dictionary<long, int> SetSort (long id, int sort)
        {
            DBCategory category = this._Service.Get(id);
            if (category.Sort != sort)
            {
                return this._Service.SetSort(category, sort);
            }
            return null;
        }

        public void Move (long id, long? toId)
        {
            DBCategory category = this._Service.Get(id);
            DBCategory to = null;
            if (toId.HasValue)
            {
                to = this._Service.Get(toId.Value);
            }
            this._Service.Move(category, to);
        }

        public void Enable (long id)
        {
            DBCategory category = this._Service.Get(id);
            if (!category.IsEnable)
            {
                this._Service.Enable(category);
            }
        }

        public void Disable (long id)
        {
            DBCategory category = this._Service.Get(id);
            if (category.IsEnable)
            {
                this._Service.Stop(category);
            }
        }

        public CategoryTree[] GetTree (CategoryGetParam param)
        {
            GoodsCategoryGet dto = new GoodsCategoryGet
            {
                IsEnable = param.IsEnable,
            };
            if (param.ParentId.HasValue)
            {
                dto.LevelCode = this._Service.Get(param.ParentId.Value, a => a.LevelCode) + param.ParentId.Value + "|";
            }
            CategoryDto[] dtos = this._Service.Gets<CategoryDto>(dto);
            return dtos.GetTree(param.ParentId.GetValueOrDefault());
        }
    }
}
